package org.windowkit.toolkit.widget;

import java.awt.AWTKeyStroke;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FocusTraversalPolicy;
import java.awt.Font;
import java.awt.HeadlessException;
import java.awt.LayoutManager;
import java.awt.MenuComponent;
import java.awt.Point;
import java.awt.PopupMenu;
import java.awt.event.ComponentListener;
import java.awt.event.ContainerListener;
import java.awt.event.FocusListener;
import java.awt.event.HierarchyBoundsListener;
import java.awt.event.HierarchyListener;
import java.awt.event.InputMethodListener;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelListener;
import java.beans.PropertyChangeListener;
import java.beans.VetoableChangeListener;
import java.util.Locale;
import java.util.Set;

import javax.swing.Action;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.border.Border;
import javax.swing.event.AncestorListener;
import javax.swing.event.MenuKeyListener;
import javax.swing.event.PopupMenuListener;

/**
 * Combines a {@link JPopupMenu} and a mouse click controller for showing it.
 * @author Rich
 */
public class PopupMenuAdapter extends MouseAdapter {


    private final JPopupMenu menu;

    PopupMenuAdapter(final JPopupMenu popupMenu) {
        this.menu = popupMenu;

    }

    PopupMenuAdapter(){
        this(new JPopupMenu());
    }

    @Override
    public void mouseReleased(final MouseEvent e) {
        if(e.isPopupTrigger()){
            menu.show(e.getComponent(), e.getX(), e.getY());
        }
    }

    public JMenuItem add(final Action a) {
        return menu.add(a);
    }

    public Component add(final Component comp, final int index) {
        return menu.add(comp, index);
    }

    public void add(final Component comp, final Object constraints, final int index) {
        menu.add(comp, constraints, index);
    }

    public void add(final Component comp, final Object constraints) {
        menu.add(comp, constraints);
    }

    /**
     * {@inheritDoc}
     */
    public Component add(final Component comp) {
        return menu.add(comp);
    }

    /**
     * {@inheritDoc}
     */
    public JMenuItem add(final JMenuItem menuItem) {
        return menu.add(menuItem);
    }

    /**
     * {@inheritDoc}
     */
    public void add(final PopupMenu popup) {
        menu.add(popup);
    }

    /**
     * {@inheritDoc}
     */
    public Component add(final String name, final Component comp) {
        return menu.add(name, comp);
    }

    /**
     * {@inheritDoc}
     */
    public JMenuItem add(final String s) {
        return menu.add(s);
    }

    /**
     * {@inheritDoc}
     */
    public void addAncestorListener(final AncestorListener listener) {
        menu.addAncestorListener(listener);
    }

    /**
     * {@inheritDoc}
     */
    public void addComponentListener(final ComponentListener l) {
        menu.addComponentListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void addContainerListener(final ContainerListener l) {
        menu.addContainerListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void addFocusListener(final FocusListener l) {
        menu.addFocusListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void addHierarchyBoundsListener(final HierarchyBoundsListener l) {
        menu.addHierarchyBoundsListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void addHierarchyListener(final HierarchyListener l) {
        menu.addHierarchyListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void addInputMethodListener(final InputMethodListener l) {
        menu.addInputMethodListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void addKeyListener(final KeyListener l) {
        menu.addKeyListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void addMenuKeyListener(final MenuKeyListener l) {
        menu.addMenuKeyListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void addMouseListener(final MouseListener l) {
        menu.addMouseListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void addMouseMotionListener(final MouseMotionListener l) {
        menu.addMouseMotionListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void addMouseWheelListener(final MouseWheelListener l) {
        menu.addMouseWheelListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void addPopupMenuListener(final PopupMenuListener l) {
        menu.addPopupMenuListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void addPropertyChangeListener(final PropertyChangeListener listener) {
        menu.addPropertyChangeListener(listener);
    }

    /**
     * {@inheritDoc}
     */
    public void addPropertyChangeListener(final String propertyName, final PropertyChangeListener listener) {
        menu.addPropertyChangeListener(propertyName, listener);
    }

    /**
     * {@inheritDoc}
     */
    public void addSeparator() {
        menu.addSeparator();
    }

    /**
     * {@inheritDoc}
     */
    public String getLabel() {
        return menu.getLabel();
    }

    /**
     * {@inheritDoc}
     */
    public Point getLocation() {
        return menu.getLocation();
    }

    /**
     * {@inheritDoc}
     */
    public Point getLocation(final Point rv) {
        return menu.getLocation(rv);
    }

    /**
     * {@inheritDoc}
     */
    public Point getMousePosition() throws HeadlessException {
        return menu.getMousePosition();
    }

    /**
     * {@inheritDoc}
     */
    public String getName() {
        return menu.getName();
    }

    /**
     * {@inheritDoc}
     */
    public Point getPopupLocation(final MouseEvent event) {
        return menu.getPopupLocation(event);
    }

    /**
     * {@inheritDoc}
     */
    public Dimension getSize() {
        return menu.getSize();
    }

    /**
     * {@inheritDoc}
     */
    public Dimension getSize(final Dimension rv) {
        return menu.getSize(rv);
    }

    /**
     * {@inheritDoc}
     */
    public Point getToolTipLocation(final MouseEvent event) {
        return menu.getToolTipLocation(event);
    }

    /**
     * {@inheritDoc}
     */
    public String getToolTipText() {
        return menu.getToolTipText();
    }

    /**
     * {@inheritDoc}
     */
    public String getToolTipText(final MouseEvent event) {
        return menu.getToolTipText(event);
    }

    /**
     * {@inheritDoc}
     */
    public int getWidth() {
        return menu.getWidth();
    }

    /**
     * {@inheritDoc}
     */
    public boolean isEnabled() {
        return menu.isEnabled();
    }

    /**
     * {@inheritDoc}
     */
    public boolean isFocusable() {
        return menu.isFocusable();
    }

    /**
     * {@inheritDoc}
     */
    public boolean isPopupTrigger(final MouseEvent e) {
        return menu.isPopupTrigger(e);
    }

    /**
     * {@inheritDoc}
     */
    public boolean isShowing() {
        return menu.isShowing();
    }

    /**
     * {@inheritDoc}
     */
    public boolean isValid() {
        return menu.isValid();
    }

    /**
     * {@inheritDoc}
     */
    public boolean isVisible() {
        return menu.isVisible();
    }

    /**
     * {@inheritDoc}
     */
    public void remove(final Component comp) {
        menu.remove(comp);
    }

    /**
     * {@inheritDoc}
     */
    public void remove(final int pos) {
        menu.remove(pos);
    }

    /**
     * {@inheritDoc}
     */
    public void remove(final MenuComponent popup) {
        menu.remove(popup);
    }

    /**
     * {@inheritDoc}
     */
    public void removeAll() {
        menu.removeAll();
    }

    /**
     * {@inheritDoc}
     */
    public void removeAncestorListener(final AncestorListener listener) {
        menu.removeAncestorListener(listener);
    }

    /**
     * {@inheritDoc}
     */
    public void removeComponentListener(final ComponentListener l) {
        menu.removeComponentListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void removeContainerListener(final ContainerListener l) {
        menu.removeContainerListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void removeFocusListener(final FocusListener l) {
        menu.removeFocusListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void removeHierarchyBoundsListener(final HierarchyBoundsListener l) {
        menu.removeHierarchyBoundsListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void removeHierarchyListener(final HierarchyListener l) {
        menu.removeHierarchyListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void removeInputMethodListener(final InputMethodListener l) {
        menu.removeInputMethodListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void removeKeyListener(final KeyListener l) {
        menu.removeKeyListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void removeMenuKeyListener(final MenuKeyListener l) {
        menu.removeMenuKeyListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void removeMouseListener(final MouseListener l) {
        menu.removeMouseListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void removeMouseMotionListener(final MouseMotionListener l) {
        menu.removeMouseMotionListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void removeMouseWheelListener(final MouseWheelListener l) {
        menu.removeMouseWheelListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void removePopupMenuListener(final PopupMenuListener l) {
        menu.removePopupMenuListener(l);
    }

    /**
     * {@inheritDoc}
     */
    public void removePropertyChangeListener(final PropertyChangeListener listener) {
        menu.removePropertyChangeListener(listener);
    }

    /**
     * {@inheritDoc}
     */
    public void removePropertyChangeListener(final String propertyName, final PropertyChangeListener listener) {
        menu.removePropertyChangeListener(propertyName, listener);
    }

    /**
     * {@inheritDoc}
     */
    public void removeVetoableChangeListener(final VetoableChangeListener listener) {
        menu.removeVetoableChangeListener(listener);
    }

    /**
     * {@inheritDoc}
     */
    public void requestFocus() {
        menu.requestFocus();
    }

    /**
     * {@inheritDoc}
     */
    public boolean requestFocus(final boolean temporary) {
        return menu.requestFocus(temporary);
    }

    /**
     * {@inheritDoc}
     */
    public boolean requestFocusInWindow() {
        return menu.requestFocusInWindow();
    }

    /**
     * {@inheritDoc}
     */
    public void setBorder(final Border border) {
        menu.setBorder(border);
    }

    /**
     * {@inheritDoc}
     */
    public void setBounds(final int x, final int y, final int width, final int height) {
        menu.setBounds(x, y, width, height);
    }

    /**
     * {@inheritDoc}
     */
    public void setComponentPopupMenu(final JPopupMenu popup) {
        menu.setComponentPopupMenu(popup);
    }

    /**
     * {@inheritDoc}
     */
    public void setCursor(final Cursor cursor) {
        menu.setCursor(cursor);
    }

    /**
     * {@inheritDoc}
     */
    public void setEnabled(final boolean enabled) {
        menu.setEnabled(enabled);
    }

    /**
     * {@inheritDoc}
     */
    public void setFocusable(final boolean focusable) {
        menu.setFocusable(focusable);
    }

    /**
     * {@inheritDoc}
     */
    public void setFocusCycleRoot(final boolean focusCycleRoot) {
        menu.setFocusCycleRoot(focusCycleRoot);
    }

    /**
     * {@inheritDoc}
     */
    public void setFocusTraversalKeys(final int arg0, final Set<? extends AWTKeyStroke> arg1) {
        menu.setFocusTraversalKeys(arg0, arg1);
    }

    /**
     * {@inheritDoc}
     */
    public void setFocusTraversalKeysEnabled(final boolean focusTraversalKeysEnabled) {
        menu.setFocusTraversalKeysEnabled(focusTraversalKeysEnabled);
    }

    /**
     * {@inheritDoc}
     */
    public void setFocusTraversalPolicy(final FocusTraversalPolicy policy) {
        menu.setFocusTraversalPolicy(policy);
    }

    /**
     * {@inheritDoc}
     */
    public void setFont(final Font font) {
        menu.setFont(font);
    }

    /**
     * {@inheritDoc}
     */
    public void setLabel(final String label) {
        menu.setLabel(label);
    }

    /**
     * {@inheritDoc}
     */
    public void setLayout(final LayoutManager mgr) {
        menu.setLayout(mgr);
    }

    /**
     * {@inheritDoc}
     */
    public void setLocale(final Locale l) {
        menu.setLocale(l);
    }

    /**
     * {@inheritDoc}
     */
    public void setLocation(final int x, final int y) {
        menu.setLocation(x, y);
    }

    /**
     * {@inheritDoc}
     */
    public void setLocation(final Point p) {
        menu.setLocation(p);
    }

    /**
     * {@inheritDoc}
     */
    public void setName(final String name) {
        menu.setName(name);
    }

    /**
     * {@inheritDoc}
     */
    public void setPopupSize(final Dimension d) {
        menu.setPopupSize(d);
    }

    /**
     * {@inheritDoc}
     */
    public void setPopupSize(final int width, final int height) {
        menu.setPopupSize(width, height);
    }

    /**
     * {@inheritDoc}
     */
    public void setSelected(final Component sel) {
        menu.setSelected(sel);
    }

    /**
     * {@inheritDoc}
     */
    public void setToolTipText(final String text) {
        menu.setToolTipText(text);
    }

    /**
     * {@inheritDoc}
     */
    public void setVisible(final boolean b) {
        menu.setVisible(b);
    }

}
